/**
 * Copyright (c) Huawei Technologies Co., Ltd. 1987-2021. All rights reserved.
*/

package com.gitee.fufu669.aspect;

import com.gitee.fufu669.utils.CacheJsonUtil;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;

// 注解
@Aspect
// 组件注解
@Component
// 注解
@SuppressWarnings({"rawtypes"})
/** @author wangfupeng */
/**
 * TODO
*/
public class LogAspect {

    /**
     * TODO
    */
    public static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
    
    // TODO
    private static String CONTENT_TYPE="Content-Type";
    
    // 注解
    @Autowired
    // TODO
    private HttpServletRequest request;

    // 注解
    @Around("within(com.gitee.fufu669.aspect.Logging+)")
    /**
     * TODO
    */
    public Object logger(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        // TODO
        long begin = System.currentTimeMillis();
        // 赋值
        String methodDescription = "NONE";
        // TODO
        Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
        // 遍历
        for (Annotation annotation : method.getAnnotations()) {
            // 判断
            if (annotation instanceof ApiOperation) {
                // TODO
                methodDescription = ((ApiOperation) annotation).value();
            }
        }

        // 创建
        StringBuilder sb = new StringBuilder("\n%%%%%%%%%%%%【")
                // 增加字符串
                .append(methodDescription).append(" ")
                // 增加字符串
                .append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
                // 增加字符串
                .append("】 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");

        // 增加字符串
        sb.append("Controller  : ").append(proceedingJoinPoint.getTarget().getClass().getSimpleName()).append("\n");
        // 增加字符串
        sb.append("Method      : ").append(request.getMethod()).append("\n");

        // 字符串赋值
        String uri = request.getRequestURI();
        // 判断是否非空
        if (uri != null) {
            // 增加字符串
            sb.append("URL         : ").append(uri).append("\n");
        }

        // 判断是否非空
        if (request.getHeader(CONTENT_TYPE) != null
                // 与判断
                && request.getHeader(CONTENT_TYPE).equals(MediaType.APPLICATION_JSON_VALUE)
                // 与判断
                && !"GET".equals(request.getMethod())) {
            // TODO
            Object[] args = proceedingJoinPoint.getArgs();
            // 判断
            if (args.length > 0) {
                // 遍历
                for (Object arg : args) {
                    // 增加字符串
                    sb.append("PostArg     : ").append(arg).append("\n");
                }
            }
        }

        // TODO
        Enumeration<String> e = request.getParameterNames();
        // 判断
        if (e.hasMoreElements()) {
            // 增加字符串
            sb.append("Parameter   : ");
            // 循环
            while (e.hasMoreElements()) {
                // 字符串赋值
                String name = e.nextElement();
                // 切分
                String[] values = request.getParameterValues(name);
                // 判断
                if (values.length == 1) {
                    // 增加字符串
                    sb.append(name).append("=").append(values[0]);
                // 否则
                } else {
                    // 增加字符串
                    sb.append(name).append("[]={");
                    // 遍历
                    for (int i = 0, length = values.length; i < length; i++) {
                        // 判断
                        if (i > 0) {
                            // 增加字符串
                            sb.append(", ");
                        }
                        // 增加字符串
                        sb.append(values[i]);
                    }
                    // 增加字符串
                    sb.append("}");
                }
                // 增加字符串
                sb.append(" ");
            }
            // 增加字符串
            sb.append("\n");
        }
        
        logger.info("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%---调用之前---%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"+sb.toString()+"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%------%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
        // TODO
        Object response = proceedingJoinPoint.proceed();

        // 判断是否是空
        if (response == null) {
            // 增加字符串
            sb.append("return      : ").append("null").append("\n");
        }
        // 否则
        else {
            // 增加字符串
            sb.append("return      : ").append(CacheJsonUtil.toJson(response)).append("\n");
        }
        // 增加字符串
        sb.append("tcost       : ").append(System.currentTimeMillis() - begin).append("ms").append("\n");
        // 增加字符串
        sb.append("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
        logger.info("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%---调用之后---%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"+sb.toString());
        // 返回
        return response;
    }
}
